一、简介
1.1 介绍
Vue.js是一个构建数据驱动的 web 界面的渐进式框架。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。 渐进式框架:Progressive,说明vue.js的轻量,是指一个前端项目可以使用vue.js一两个特性也可以整个项目都用 vue.js。 自底向上逐层应用:作为渐进式框架要实现的目标就是方便项目增量开发。 地址:https://cn.vuejs.org/v2/guide/
1.2 使用
- 在html页面使用script引入vue.js的库即可使用。
- 使用Npm管理依赖,使用webpack打包工具对vue.js应用打包。 大型应用推荐此方案。
- Vue-CLI脚手架 使用vue.js官方提供的CLI脚本架很方便去创建vue.js工程雏形。
1.3 功能
声明式渲染 Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统。 比如:使用vue.js的插值表达式放在Dom的任意地方, 差值表达式的值将被渲染在Dom中。
条件与循环 dom中可以使用vue.js提供的
v-if、v-for等标签,方便对数据进行判断、循环。双向数据绑定 Vue 提供
v-model指令,它可以轻松实现Dom元素和数据对象之间双向绑定,即修改Dom元素中的值自动修改绑 定的数据对象,修改数据对象的值自动修改Dom元素中的值。处理用户输入 为了让用户和你的应用进行交互,我们可以用 v-on 指令添加一个事件监听器,通过它调用在 Vue 实例中定义的 方法
组件化应用构建 vue.js可以定义一个一个的组件,在vue页面中引用组件,这个功能非常适合构建大型应用。
二、基础
2.1 MVVM模式
MVVM是Model-View-ViewModel的简写。它本质上就是MVC 的改进版。MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开 MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model) Vue.js 是一个提供了 MVVM 风格的双向数据绑定的 Javascript 库,专注于View 层。它的核心是 MVVM 中的 VM,也就是 ViewModel。 ViewModel负责连接 View 和 Model,保证视图和数据的一致性 vue.js是一个MVVM的框架,理解MVVM有利于学习vue.js。
- MVVM拆分解释为:
- Model:负责数据存储
- View:负责页面展示
- View Model:负责业务逻辑处理(比如Ajax请求等),对数据进行加工后交给视图展示
- MVVM要解决的问题是将业务逻辑代码与视图代码进行完全分离,使各自的职责更加清晰,后期代码维护更 加简单
2.2 页面引入vue的js文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF‐8">
<title>vue.js入门程序</title>
<script src="/js/vue/vue.min.js"></script>
</head>
<body>
<div id="app">
{{name}}
<!‐‐ 在Vue接管区域中使用Vue的系统指令呈现数据 这些指令就相当于是MVVM中的View这个角色 ‐‐>
</div>
</body>
<script>
// 实例化Vue对象
//vm :叫做MVVM中的 View Model
var VM = new Vue({
el:"#app",//表示当前vue对象接管app的div区域
data:{
name:'传智播客'// 相当于是MVVM中的Model这个角色 }
});
</script>
</html>2.3 模板语法
插值
- 使用
- 内容可以为data中的变量名、运算、或者表达式
- 向标签中添加html代码
v-html标签,后跟data中的变量名
- 使用
指令
v-bind:- 绑定属性
v‐bind可以将数据对象绑定在dom的任意属性中。可以给dom对象绑定一个或多个特性,例如动态绑定style和class,如:
<img v‐bind:src="imageSrc"> <div v‐bind:style="{ fontSize: size + 'px' }"></div>- 可简写为
:
v-on:
- 绑定事件,事件对应名称为methods中的方法名
v-on:click:监听点击v-on:keydown:监听案件v-on:mouseover:监听鼠标移入
template
- 只在VUE代码中显示,在html网页不显示,框选其中内容,但不影响其选择级别,和标签外的标签同级
2.4 绑定多个class和style属性
- 使用对象语法
- 使用对象语法向其中添加内容需使用VUE.set方法
- 使用数组语法
- 向其中添加元素使用push方法即可
2.5 条件渲染
v-if- 对取值进行判断,为ture则显示
v-else- 与if标签相反
v-else-if- 多重判断
v-show- if相同功能,区别是v-show是将所修饰的标签隐藏,if是删除
2.6 列表渲染
v-forin of- 对数组进行遍历
v-for="元素名 in 数组名"
- 对数组进行遍历
- key
- 对vue检测进行优化,没有key值则依靠索引进行对比,若不同则进行修改,修改的多,效率低,设定key值则对key值进行判断,值未变则不修改,若中间有插入的则插入,不影响其他,
- key值是每项都有且唯一的id
2.7 数组更新检测
vue可以检测到的变动
- push() pop() shift() unshift() splice() sort() reverse()
生成新的数组
- filter(), concat() 和 slice() ,map(),新数组替换旧数组
- 生成的新数组与原数组不是同一个,需将新数组替换为旧数组
不能检测到的变动
vm.items[indexOfItem] = newValue- 根据索引修改值
解决方案
Vue.set(哪个数组,索引位置, 新的值)- 使用splice方式
过滤显示数组内容
- 通过filer方法中调用函数判断
this.list.filter((item)=>item.indexOf(this.mytext)>-1)
- 通过filer方法中调用函数判断
2.8 事件处理
添加事件
直接写表达式
- 简单的事件处理可以使用该方式
写函数名不加括号
- 获取的是该事件的对象
写函数名后加括号
- 传参时使用,既想获取事件对象,又想传参时在括号中添加$event
事件修饰符
是在事件绑定参数后用.连接的,如@click.stopstop
- 阻止父标签的事件触发
prevent
- 阻止默认事件
- 如a标签的跳转
- 阻止默认事件
self
- 只对当前标签元素有效,对其子标签无效
once
- 事件只触发一次
event.stopPropagation();//阻止冒泡
按键修饰符
在
@keydown.加案件对应的值即可为对应的案件添加相应的按键事件,.enter和上下左右键可以直接写字符,vue对其进行了封装如:
.enter .tab .delete (捕获 "删除" 和 "退格" 键) .esc .space .up .down .left .right .ctrl .alt .shift .meta v-on:keyup.enter
事件解绑
- 通过一个变量为boolean类型的值与事件&&连接,修改变量的值即可使事件是否执行
@click="isFirst && handleLiClick1()"
- 通过一个变量为boolean类型的值与事件&&连接,修改变量的值即可使事件是否执行
2.9 表单控件
v-model- 对输入框中的值和data中的变量值进行双向绑定,哪一方进行修改都会改变
- 在表单控件或者组件上创建双向绑定 2、v-model仅能在如下元素中使用:input 、select 、textarea 、components(Vue中的组件)
- 如对复选框绑定时,data中对应一个数组,每个复选框标签对应一个值,当勾选是即可使对应的值存入对应的数组中,数组中有某个值时,该复选框的状态也是被勾选的状态(单选框同理,对应的data中变量取值为字符串)
- 修饰符
.lazy- 不同步更新,只在失去焦点时同步一次
.number- 格式化数字,将输入内容强制转换为数字,若转换不了则失效
.trim- 去除首位空格
v-html可解析页面v-text可以将一个变量的值渲染到指定的元素中,它可以解决插值表达式闪烁的问题
三、组件
3.1 实现数据请求
- fetch
get方式
fetch("**").then(res=>res.json()).then(res=>{console.log(res)})
获取内容转为json格式
fetch("**").then(res=>res.text()).then(res=>{console.log(res)}- 内容为文本格式
post方式
jsfetch("**",{ method:'post', headers: { //请求头信息 "Content‐Type": "application/x‐www‐form‐urlencoded" }, body: "name=kerwin&age=100" //传递的值 }).then(res=>res.json()).then(res=>{console.log(res)});
fetch("/users",{
method:'post',
// credentials: 'include', //默认不携带cookie,添加则携带
headers: {
"Content‐Type": "application/json" //json格式
},
body: JSON.stringify({ //传递的对象需转为json格式
name:"kerwin",
age:100
})
}).then(res=>res.json()).then(res=>{console.log(res)});- axios
- get
axios.get("json/test.json").then(res=>{
console.log(res.data);//真正的后端数据藏在res.data
})- post
axios({
url:"", //请求地址
method: "",//请求方式
headers:{}, //携带的请求头信息
data:{} //携带数据
}).then(res=>{
console.log(res.data);
})3.2 计算属性
在computed中添加函数,调用时后面不加括号,必须有返回值 (调用属性和计算不需要加括号,调用方法需要)
页面中多次调用时,只在第一次计算结果,后面调用从缓存中取值
特点
- 计算属性是基于它们的依赖进行缓存的。
- 计算属性只有在它的相关依赖发生改变时才会重新求值
适用场景
- 在一个页面多次调用计算结果,如购物车总金额计算,模糊查询结果
watch
- 与computed同属于vue的属性,可以监听某个data中属性的值的改变,监听必须保证其中属性名与data中的属性名保持一致
3.3 混入mixins
- 混入 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。 混入对象可以包含任意组件选项
- 可以将其他对象的方法加入vue代码中,提高代码复用性
- mixins对应的是一个数组,可以添加多个对象
- 若混入的对象与当前vue对象的方法中包含同名方法,则调用vue的方法
3.4 组件
- 组件作用
- 扩展html元素,封装可重用的代码
- 注册方式
- 全局组件
Vue.component- 代码实例
- 全局组件
Vue.component("navbar",{
template: `htmldom节点,只能有一个根标签`,
data(){
return {data必须是函数形式}
// 组件与组件 的状态需要相互隔离, 要设计成函数。
},
methods:{ 与之前相同},
components:{
})- 局部组件
- 使用components属性中添加组件
- 代码示例
- 使用components属性中添加组件
navbarchild:{
template:`<div>navbarchild--{{title}}</div>`,
data(){ return { } }
} }调用方式
- 使用标签调用,标签为组件名
注意事项
- *自定义组件需要有一个root element
- *父子组件的data是无法共享
- *组件可以有data,methods,computed....,但是data 必须是一个函数
父子组件之间传值
父传子
- 父组件在调用子组件的标签时对其添加属性,属性名自定义,若传递的是非字符串类型如布尔类型的值需前面加v-bind绑定
- 子组件使用props属性获取父组件传递的值,可为数组类型或对象类型,数组类型中为父组件传值的属性名,获取后可作为data中的属性值使用,若为对象类型,则对象中为 属性名:类型
props:{name:Number}Number,String,Boolean,Array,Object,Function,null(不限制类型)- 添加属性验证若所传递的值类型不符合,则在控制台报错
子传父
- 父组件在调用子组件的标签中绑定一个事件,绑定名称自定义,事件名后不加括号,在vue的methods属性中添加事件,添加形参可以获取子组件传来的值
- 子组件向父组件传值时,需要添加事件,在事件中调用
this.$emit("父组件绑定的名称",向父组件传递的数据)
ref方式
- 在标签中添加ref属性,对应的名称自定义
- 在方法中可以通过this.$refs获取页面所有的具有的ref属性的标签对象
- 对于普通标签,取到的是原生节点dom对象 对于组件标签,取到的是组件对象
- 调用某个指定对象通过
this.$refs.ref属性对应的名称调用,可以查看和修改对象的信息,也可用于子传父和父类调用子类信息
兄弟之间传值(bus)
- 首先创建一个新的空白vue实例
- 新建一个空白实例作为桥梁
- 发送方添加事件,
新建实例名.$emit(“事件名”,传递的信息)发送 - 接收方需在
- 首先创建一个新的空白vue实例
mounted(){
新建实例名.$on(“事件名”,函数(可通过形参获取值))
}中添加
monted是生命周期的钩子,在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作
- 通过$on对事件进行监听
传值还可在外部模块中建立,模块只会加载一次,因此,不同的部分导入的都是同一个实例
动态组件
<component>元素,动态地绑定多个组件到它的 is 属性 is后可以是全局组件或局部组件,is指向哪个组件就显示哪个
<component :is="who"></component><keep-alive>保留状态,避免重新渲染 即在切换组件后再切换回来仍保持切换之前组件被修改后的状态
四、虚拟dom与diff算法
vue管理会创建一个虚拟dom节点,当发生改变时会对dom节点进行对比
对比原则
- 逐层对比,只对比相应层级的dom节点
- 同key值对比,key值指定是唯一的,对key值进行对比就能发现哪些不对应或者是新增的
- 同组件对比,如对标签类型进行对比,若不相同,则直接对其进行删除,新建新的节点
五、高级用法
5.1 slot插槽
单个插槽
概述
- 即在子组件中使用
<slot>标签占位,在调用的父组件的标签内填写要在子组件中添加的内容,将父组件中的内容添加至子组件中,父组件的内容在父组件的作用域中编译,可调用父组件的属性及事件
- 即在子组件中使用
适用场景
- 需要依赖父组件属性的子组件,设定成模板,需用户自己添加内容的组件
具名插槽
- 对插槽起一个名字,在父组件调用时,在父组件添加的内容标签添加slot属性,该属性与想替换的插槽名字对应
5.2 transition过渡动画
- 单元素单组件过渡
- 使用自带的动画
- 1.将类选择器的动画添加,类选择器的命名规则如: enter-active之前的名字为自定义
- 使用自带的动画
.kerwinfade-enter-active, .kerwinfade-leave-active {
transition: all 1.5s;
}
.kerwinfade-enter, .kerwinfade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
transform: translateX(100px);
}2.将需要添加动画的元素或组件使用
<transition>标签包裹,并将name属性赋值为自定义名称- 结合animate.css动画库
- 1.引入animate的css文件
- 对
<transition>标签的特定class 赋animate的样式的值
- 结合animate.css动画库
<transition enter-active-class="animated bounceInRight" leave-active-class="animated bounceOutRight">
<p v-show="isShow">33333333333333333</p>
</transition>多组件的过渡
- 还是只有一个主标签,只是内容改变,如v-if和v-else只显示一个的标签,如果他们修饰的标签类型相同,当添加切换动画时,由于是相同标签,vue会直接复用标签,不涉及删除修改,若想添加动画,则需添加key值,添加mode属性的值修改动画执行的方式 :in-out 先来再走 out-in先走再来
<component>动态组件 标签修改显示组件 也涉及动画 ,同理
- 还是只有一个主标签,只是内容改变,如v-if和v-else只显示一个的标签,如果他们修饰的标签类型相同,当添加切换动画时,由于是相同标签,vue会直接复用标签,不涉及删除修改,若想添加动画,则需添加key值,添加mode属性的值修改动画执行的方式 :in-out 先来再走 out-in先走再来
列表过度
- 使用transition-group不同于transiton,他会以一个真实的元素呈现,默认为一个span标签,可使用tag属性更换为其他标签元素
- 必须提供唯一的key属性值
- 注意:当使用索引当作key值时,若遍历后删除中间的元素,key值是最后一个key值删除,其他元素改变,因此添加移除动画时都会显示在最后一个上
- 使用transition-group不同于transiton,他会以一个真实的元素呈现,默认为一个span标签,可使用tag属性更换为其他标签元素
可复用过渡
- 将组件内的内容使用动画标签包裹,将动画效果封装在组件里
5.3 生命周期

- beforeCreate(创建vue实例前'):
- 数据还没有监听,没有绑定到vue对象实例,同时也没有挂载对象
- created(创建vue实例后):
- 数据已经绑定到了对象实例,但是还没有挂载对象
- beforeMount(挂载到dom前):
- 模板已经编译好了,根据数据和模板已经生成了对应的元素对象,将数据对象关联到了对象的el属性,el属性是一个HTMLElement对象,也就是这个阶段,vue实例通过原生的createElement等方法来创建这个html片段,准备注入到我们vue实例指明的el属性所对应的挂载点
- mounted(挂载到dom后)
- 将el的内容挂载到了el,相当于我们在jquery执行了(el).html(el),生成页面上真正的dom,上面我们就会发现dom的元素和我们el的元素是一致的。在此之后,我们能够用方法来获取到el元素下的dom对象,并进 行各种操作
- beforeUpdate(数变化更新前)
- 数据更新到dom之前,我们可以看到$el对象已经修改,但是我们页面上dom的数据还没有发生改变
- updated(数据变化更新后)
- dom结构会通过虚拟dom的原则,找到需要更新页面dom结构的最小路径,将改变更新到dom上面,完成更新
- beforeDestroy(vue实例销毁前),destroyed(vue实例销毁后)
- 实例的销毁,vue实例还是存在的,只是解绑了事件的监听还有watcher对象数据与view的绑定,即数据驱动
Vue在实例化的过程中,会调用这些生命周期的钩子,可以在函数中定义业务逻辑
5.4 swiper
动态效果插件
- 注意:防止swipe初始化过早
解决异步请求动态数据的问题
- 当添加动态效果的标签是ajax异步请求后获得的,应在请求结束后再新建swiper对象
- vue的解决方式:在调用组件的标签中绑定key值,如果发生改变,key值变化则对其进行销毁,再新建一个,因此会再次执行vue的mounted生命周期,在此生命周期中新建swiper则能解决
5.5 指令
- 可以获取dom节点和对dom节点的生命周期进行检测
- 声明
- 使用
Vue.directive('指令名',{
dom的生命周期状态(el, bind,vnode){ }
})- el是当前dom对象,bind为当前节点声明所传递的值,可以为对象,vnode(vnode.context)可以使用newvnode和oldvnode获取更改前和更改后的dom节点,vnode.context可以拿到当前的vue实例
- 虚拟dom,可以理解为对dom的备份,当修改后,会再形成一个dom,将两个dom节点对比后就能发现哪些不同
调用
- 在节点中添加属性v-指令名,后可跟值,在指令中可使用bind进行获取
this.$nextTick- 再监听dom完成更新后调用回调函数
this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。
5.6 过滤器
- 作用:对数据和字符串格式的转换
- 声明方式
Vue.filter(“过滤器名称”,function(传递的形参){
对传递的值进行处理并返回
})- 调用方式
- 在需要进行转换的值后加“|”和过滤器名称
5.7 一个js文件中多个函数到处方法
封装一个对象,将多个函数引入,导出该对象
- 引入时需导入对象
- 导入时必须导入全部
将export后的default删除,更改为
{函数1,函数2.。。}方式- 引入时导入
{函数名,函数2} - 该方式可以导入某个函数
- 引入时导入
六、vue脚手架
6.1 vue脚手架
https://blog.csdn.net/weixin_30918415/article/details/101076043
单文件组件https://cn.vuejs.org/v2/guide/single-file-components.html
html<template> html代码 </template> <script> js代码 </script> <style> css代码 </style> <template> html代码 </template> <script src="相对路径的外部的js"></script> <style src="相对路径的外部的css"></style>vue-cli3.0的使用
npm install -g @vue/cli (一次安装) vue create myapp *npm run serve 开发环境构建 *npm run build 生产环境构建 *npm run lint 代码检测工具 style标签 加上scoped属性,css局部生效 style标签 加上lang="scss",支持scssVue.config.js的配置
proxy代理https://cli.vuejs.org/zh/config/#全局-cli-配置
devServer: { port:8000, //随便改端口号 proxy: { '/v4': { target: 'https://m.maizuo.com', host: 'm.maizuo.com', changeOrigin:true } } }alias别名配置
@ is an alias to /src
vue.config.js 中配置
publicPath: './ ',关闭eslint
Json-server实现mock数据
https://github.com/typicode/json-serverMPA(多页面)应用的配置
https://cli.vuejs.org/zh/config/#pagesmodule.exports = { pages: { index: { // page 的入口 entry: 'src/index/main.js', // 模板来源 template: 'public/index.html', // 在 dist/index.html 的输出 filename: 'index.html', // 当使用 title 选项时, // template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title> title: 'Index Page', // 在这个页面中包含的块,默认情况下会包含 // 提取出来的通用 chunk 和 vendor chunk。 chunks: ['chunk‐vendors', 'chunk‐common', 'index'] }, // 当使用只有入口的字符串格式时, // 模板会被推导为 `public/kerwin.html` // 并且如果找不到的话,就回退到 `public/index.html`。 // 输出文件名会被推导为 `kerwin.html`。 kerwin: 'src/kerwin/main.js' } }
利用vue-cli进行组件化开发
- 迁移todolist、swiper案例到vue-cli中
6.2 vue单文件
css作用域
- style标签 加上scoped属性,css局部生效 style标签 加上
lang="scss",支持scss
- style标签 加上scoped属性,css局部生效 style标签 加上
解决请求跨域
通过Vue.config.js的配置proxy代理
https://cli.vuejs.org/zh/config/#%E5%85%A8%E5%B1%80-cli-%E9%85%8D%E7%BD%vue.config.js 中配置
publicPath: ./
导入问题
- 用@符号 表示src,相当于根目录,绝对路径
6.3 vue多页面开发
https://cli.vuejs.org/zh/config/#pag
6.4 别名
通过配置slias属性,对该路径起一个别名
@ is an alias to /src
6.5 路由
修改
router.js文件在其中添加匹配的路径的所加载的组件- 添加的属性
path:路由匹配的路径component对应的 组件名children 嵌套的路由(不必须) name 路由别名 alias 路径别名 - 需导入相应的组件,并在主页面的vue对象中添加router属性
- 使用
<router-view>标签在指定的位置添加通过路径匹配的组件
- 添加的属性
导航
声明式导航
- 通过
<router-link>组件可以设置点击该标签内容跳转指定路径- to属性后跟要跳转的路径 tag可以设置该标签的类型 如li标签 span标签
- 通过
编程式导航
- 在方法中调用通过
this.$router.push('跳转的路径')
- 在方法中调用通过
重定向
- 指定路由的跳转界面
- 在router.js中配置路径通过redirect属性匹配重定向的地址,
/表示进入主页面自动加载的路径,*表示如果没有配置该路径则默认跳转的路径
- 在router.js中配置路径通过redirect属性匹配重定向的地址,
- 指定路由的跳转界面
路由嵌套
- 在router.js的对象中添加children的属性
- 添加的嵌套路由和路由配置相同,调用方式也相同,只能在父路由中调用
- 在router.js的对象中添加children的属性
动态匹配
- 在编程式导航中,可以在路径中匹配动态参数,传递给路由,在路由中在路径后使用:参数名获取,参数名应该相同
- 注意,后可跟多个参数
命名路由
- 在路由中添加name属性,在编程式导航中可通过
this.$router.push({name:路由的名字,params:{参数名:值}})- 参数没有即不是动态路由
- 在路由中添加name属性,在编程式导航中可通过
命名视图
- 在router.js的component属性中添加别名:对应的组件名,在
<router-view>标签中可通过属性name指向别名
- 在router.js的component属性中添加别名:对应的组件名,在
模式
在router.js的router实例中添加mode属性 默认为hash,可修改为history
hash
- 该模式访问的路径中不含#
- 切换和切换监听
location.hash可以获取当前路径信息window.onhashchange监听路径的切换
history
路径中不含
#但需要后端进行处理切换和切换监听
history.pushState切换window.onpopstate监听路径的切换
获取当前路由对象
- 通过
this.$route this.$router获取的是所有对象
- 通过
路由守卫|拦截
全局守卫
添加方式
- 在router.js中新增一个方法
router.beforeEach((to,from,next) =>{进行一些判断 调用next()放行})- to表示要去的路由的对象,from是来的时候的对象,
next()放行
- to表示要去的路由的对象,from是来的时候的对象,
- 在router.js中新增一个方法
局部守卫
- 添加方式
- 在vue对象中添加
biroteRouteEnter(to,from,next){进行判断}- 例子
- 在vue对象中添加
- 添加方式
<script type="text/javascript">
export default {
beforeRouteEnter (to, from, next) {
if(true){
next();
}else{
next("/login");
}
},
}
</script>- 生命周期
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建- `beforeRouteUpdate (to, from, next) {`
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`- `beforeRouteLeave (to, from, next) {`
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`6.6 iconfont
图标的css组件
引入方式
- 将文件放入public文件夹中,在index页面中引入css文件
- 将文件放入
src/assets文件夹中,在script中使用import中导入css文件
添加方式
- 在class中添加iconfont 和对应的图标名
6.7 Better-Scroll
概述
- 主要完成的功能需要包含Better-Scroll实现页面中拖动滚动、拉 动属性等功能
https://ustbhuangyi.github.io/better-scroll/doc/zh-han
- 主要完成的功能需要包含Better-Scroll实现页面中拖动滚动、拉 动属性等功能
调用过程
- 导入betterScroll包
- 为要实现的拖动的最外层添加一个固定宽度,然后设置一个class名
- 在
this.$nextTick(()=>{new BetterScroll(‘class名’)})
七、vuex
7.1 概述
- Vuex是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生
- vuex组件是独立出来的一个组件,将所有的与状态有关的共享变量放入其中进行管理
7.2 作用
状态共享
数据快照
- 缓存后端数据,避免重复请求,影响用户体验,主要用于不常改变的数据
- 在state中的值可以经过判断,如果为空则获取,不为空则从缓存中获取,缓存在内存中
- 缓存后端数据,避免重复请求,影响用户体验,主要用于不常改变的数据
时光旅行
- 调试
7.3 状态获取方式
在
vuex(store.js)中定义vuex信息,在vue实例中导入vuex的store并引用vuex的属性 state存放状态的对象, mutations存放同步修改状态方法的对象 actions存放异步修改状态方法的对象 getters 对state中的属性进行处理,比如只显示前五个数据
- mutations可设计为常量写法常量属性方式
[常量名]表示获取常量值对应的值 使用常量方式使代码可维护性变强
- mutations可设计为常量写法常量属性方式
获取方式
- 通过
this.$store(定义的vuex名).state(存放状态信息的对象名).(状态参数名)
- 通过
7.4 修改方式
同步
- 通过
this.$store(定义的名).commit(自定义参数名,值)- 自定义参数名需与vuex对象的mutations中的名字对应
- 在mutations的方法中获取两个值,第一个为state的对象,第二个为传递的值
- 通过
异步
- 通过
this.$store(定义的名).dispatch(自定义参数名,值)- 自定义参数名需与vuex对象的actions中的名字对应
- 在actions中获取的形参为store的对象,修改status值需通过调用mutations中的方法,如
store.commit('mutations中的方法名',参数),它不能直接修改state
- 通过
7.5 调试工具
- 浏览器vue插件
7.6 计算属性获取状态值
首先在v-show中添加一个计算属性参数名
通过一个计算属性方法中转,仍使用之前方式获取
导入vuex的mapState函数方法,在计算属性对象后:
mapState(['参数名'])- 导入方式为
导入vuex的mapState函数方法,在计算属性对象
{...mapState(['参数名'])}- ...表示展开,显示其中全部,可用于合并数组和对象
- 相当于将查询方法合并到计算属性对象中
7.7 getters
对state中的数据进行处理
创建方式
- 在getters对象中添加方法,返回所需的state值
调用方式
this.$getters.(方法名)- 调用方式同state
7.8 注意
- (1)应用层级的状态应该集中到单个 store 对象中。
- (2)提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。
- (3)异步逻辑都应该封装到 action 里
八、组件库
8.1 第三方插件
8.2 使用第三方ui框架
pc
element UI iview
移动
8.3 移动端布局
8.3.1 移动端布局及适配方式
dpr与viewport
rem等比缩放方案
1px边框问题 (为什么移动端css里面写了1px, 实际看起来比1px粗.)
在devicePixelRatio = 2 时,输出viewport: <meta name="viewport" content="initial‐scale=0.5, maximum‐scale=0.5, mini mum‐scale=0.5, user‐scalable=no"> 在devicePixelRatio = 3 时,输出viewport: <meta name="viewport" content="initial‐scale=0.3333333333333333, maximumscale= 0.3333333333333333, minimum‐scale=0.3333333333333333, user‐scalable=n o"> https://www.cnblogs.com/lunarorbitx/p/5287309.html
8.3.2 移动端事件相关
click事件300ms延迟 为了检测是否还有双击或捏开
解决:(1) 设置meta viewport (2) fastclick
Zepto.js
Zepto是一个轻量级的针对现代高级浏览器的JavaScript库, 它与jquery有着类似的api。使用需要注意以下几点:
- 提供 jQuery 的类似的API,但并不是100%覆盖 jQuery;
- Zepto不支持旧版本的Internet Explorer浏览器(<10);
- zepto添加了完整的touch手势支持;解决300ms延时(tap取代click,需要引入zepto.touch.js)
Hammer.js
HammerJS是一个优秀的、轻量级的触屏设备手势库 hammer.js https://github.com/hammerjs/hammer.js vue touch https://github.com/vuejs/vue-touch/tree/next
九、高级应用
9.1 SSR
使用vue对搜索引擎优化需借助vue-server-renderer 经过 渲染后可以通过百度爬虫爬到
9.2 Nuxt.js
服务端渲染, 解决首屏加载速度, 和 seo
安装与介绍
npx create-nuxt-app <项目名>服务端渲染, 解决首屏加载速度, 和 seo问题Nuxt.js的配置
路由配置
要在页面之间使用路由,我们建议使用
<nuxt-link>标签。 支持activeClass,tag一级路由
路由由在page文件夹下的组件加载后自动创建
嵌套路由
在pages文件夹下创建与父组件的名字相同的文件夹,并在父组件中添加
<nuxt-child>来表示子组件的位置pages/ ‐‐| film/ ‐‐‐‐‐| nowplaying.vue ‐‐‐‐‐| comingsoon.vue ‐‐| film.vue
动态路由
- 创建一个文件夹名字与在需要传值的路径名相同(该路径是用该文件夹表示,页面由动态参数组件展示),在文件夹中创建一个vue名字是以_下划线开头,后面是传递的参数名
pages/
‐‐| detail/
‐‐‐‐‐| _id.vue- 获取动态路由参数
asyncData({params}){
console.log(params.id);
}重定向
- 在nuxt.config.js中添加配置
组件
- 全局组件
- 在layouts文件夹下的default.vue中添加
- 要在页面之间使用路由,我们建议使用
<nuxt-link>标签。 支持activeClass,tag - 要在页面之间使用路由,我们建议使用
<nuxt-link>标签。 支持activeClass,tag
- 全局组件
导航
- 要在页面之间使用路由,我们建议使用
<nuxt-link>标签。 支持activeClass,tag
- 要在页面之间使用路由,我们建议使用
定制模板
- 在layouts中新增组件(相当于模板),在子组件的export default中添加属性
layout:"模板名" //指定模板是谁 - 所有的组件都加在里面, 但是有些页面 可能不一样,就可以使用 个性化定制页面
- 在layouts中新增组件(相当于模板),在子组件的export default中添加属性
视图
- 在layout 里面 写好default.vue 可以认为这是根组件的模板了, 所有的组件都加在里面, 但是有些页面 可能不一样,就可以使用 个性化定制页面。
异步数据
使异步数据能够被百度爬虫加载到
在asyncData对象中进行异步数据请求
- 是先在后端渲染,然后在前端渲染
- 如果在其中进行ajax请求,使用this获取不了当前对象,应对使用ajax请求获取的数据进行返回,并把ajax的方法得到的结果进行返回
- 其后参数可跟data,为全部对象,也可用
{data对象的属性名,拿到该对象}
如果组件的数据不需要异步获取或处理,可以直接返回指定的字面对象作为组件的数据。
export default { data () { return { foo: 'bar' } } }反向代理的配置 (重启服务器)
npm i @nuxtjs/proxy ‐D 在 nuxt.config.js 配置文件中添加对应的模块,并设置代理 modules: [ '@nuxtjs/axios', //添加axios '@nuxtjs/proxy' //添加proxy模块 ], axios: { proxy: true }, proxy: { '/api': { target: 'http://example.com', pathRewrite: { '^/api' : '/' } } }
反向代理
- 在nuxt.config.js中配置
- 通过判断在客户端是代理路径,在服务端是完整路径
操作dom的问题
- 需在nuxt.config.js中配置,使其在(客户端)浏览器环境下进行渲染,在服务端不能渲染
vuex状态树
需要添加
store/index.js文件,并对外暴露一个Vuex.Store新的实例每次访问都要返回一个实例, 防止交叉请求状态污染import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = () => new Vuex.Store({ state: { counter: 0 }, mutations: { increment (state) { state.counter++ } } }) export default storefetch 方法用于在渲染页面前填充应用的状态树(store)数据,与 asyncData 方法类似,不同的是它不会设置组件的数据。如果页面组件设置了 fetch 方法,它会在组件每次加载前被调用(在服务端或切换至目标路由之前)
export default { async fetch ({ store, params }) { let { data } = await axios.get('http://my‐api/stars') store.commit('setStars', data) } }
nginx
- 配置文件nginx.conf
- location
root表示根目录 index表示加载哪个页面, 中间可以用空格隔开添加多个
- error_page 表示错误页面 404 (中间空格隔开可使页面对应多个错误) 对应的404错误页面
- alias可以设置别名,使其指向真实路径,alias后跟真实路径,location后为别名
- location后跟
/ajax/表示向ajax发送请求就走里面的代理 请求路径前缀需加/ajax/里面添加proxy_pass可添加代理的域名,实现跨域功能- 可定义多个,请求路径(
/ajax/)不同,访问的也不同
- 可定义多个,请求路径(
- location
- 配置文件nginx.conf
十、项目目录

assets:存放一些静态文件,如图片。
base:存放基础组件
base/api:基础api接口
base/component:基础组件,被各各模块都使用的组件
base/router:总的路由配置,加载各模块的路由配置文件。
common:工具类
component:组件目录,本项目不用。
mock:存放前端单元测试方法。
module:存放各业务模块的页面和api方法。
下级目录以模块名命名,下边以cms举例:
cms/api:cms模块的api接口
cms/component:cms模块的组件
cms/page: cms模块的页面
cms/router:cms模块的路由配置
statics:存放第三方组件的静态资源
vuex:存放vuex文件,本项目不使用
static:与src的平级目录,此目录存放静态资源
它与assets的区别在于,static目录中的文件不被webpack打包处理,会原样拷贝到dist目录下